home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-01-11 | 20.1 KB | 457 lines | [TEXT/pdos] |
- Apple II
- Technical Notes
- _____________________________________________________________________________
- Developer Technical Support
-
- Apple IIGS
- #34: Low-Level QuickDraw II Routines
-
- Revised by: Dave "Evad Snoyl" Lyons, Keith Rollin,
- Steven Glass, Matt Deatherage & Eric Soldan January 1991
- Written by: Steven Glass May 1988
-
- This Technical Note describes the low-level routines which QuickDraw II uses
- to do much of the work in standard calls and mechanisms for calling these
- routines and accessing their data.
- Changed since November 1990: Added a Note on custom bottleneck procedures and
- updated information on ShieldCursor and UnShieldCursor.
- _____________________________________________________________________________
-
- QuickDraw II lets you customize low-level drawing operations by intercepting the
- "bottleneck procedures." QuickDraw II calls an appropriate "bottleneck proc"
- every time it receives a call to draw an object, measure text, or deal with
- pictures. For example, if an application calls PaintOval, QuickDraw II calls
- StdOval to do the real work, and if an application calls InvertRgn, QuickDraw II
- calls StdRgn to do the work.
-
- Installing your own bottleneck procedures is a little bit tricky. The QuickDraw
- II SetStdProcs call accepts a pointer to a 56-byte ($38 hex) record and fills
- that record with the addresses of the standard bottleneckprocedures of QuickDraw
- II. You may modify this record by replacing those addresseswith the addresses
- of your own custom bottleneck procedures minus one. (QuickDraw II pushes the
- address on the stack and executes an RTL to it, so the address in the record
- must point to the byte before the routine.)
-
- Note: A custom bottleneck procedure must not begin at the first byte of a
- segment. If it does, then the segment could load at the beginning of a
- bank, and the address minus one would be in the wrong bank and RTL would
- transfer control to the wrong location. (See Apple IIgs Technical Note
- #90, 65816 Tips and Pitfalls.)
-
- After installing your own procedures, you use SetGrafProcs to tell QuickDraw II
- about them. The format of this call is as follows (taken from the E16.QUICKDRAW
- file in APW):
-
- ostdText GEQU $00 ; Pointer - QDProcs -
- ostdLine GEQU $04 ; Pointer - QDProcs -
- ostdRect GEQU $08 ; Pointer - QDProcs -
- ostdRRect GEQU $0C ; Pointer - QDProcs -
- ostdOval GEQU $10 ; Pointer - QDProcs -
- ostdArc GEQU $14 ; Pointer - QDProcs -
- ostdPoly GEQU $18 ; Pointer - QDProcs -
- ostdRgn GEQU $1C ; Pointer - QDProcs -
- ostdPixels GEQU $20 ; Pointer - QDProcs -
- ostdComment GEQU $24 ; Pointer - QDProcs -
- ostdTxMeas GEQU $28 ; Pointer - QDProcs -
- ostdTxBnds GEQU $2C ; Pointer - QDProcs -
- ostdGetPic GEQU $30 ; Pointer - QDProcs -
- ostdPutPic GEQU $34 ; Pointer - QDProcs -
-
- The following code fragment shows how you might replace the StdRect procedure
- with your own for a given window:
-
- pha ; open a test window
- pha
- PushLong #MWindData ; standard setup for NewWindow
- _NewWindow
- _SetPort
-
- PushLong #MyProcs ; get a record to modify
- _SetStdProcs
-
- ldy #ostdRect ; get the low word of my rectangle routine
- lda #myRect-1 ; (minus one) and patch it in to the record
- sta myProcs,y
- lda #^myRect ; do the same for the high word
- sta myProcs+2,y
-
- PushLong #MyProcs ; install the procs
- _SetGrafProcs
-
- The interface to bottleneck procedures is different from the interface to other
- QuickDraw II routines; you do not make calls via the tool dispatcherand you pass
- most parameters on the direct page and in registers (rather than on the stack).
- To write your own bottleneck procedures, you have to know where the inputs to
- each call are kept and how to call the standard procedures from inside your own
- procedures.
-
- The standard bottleneck procedures are accessed through vectors in bank $E0.
-
- StdText $E01E04
- StdLine $E01E08
- StdRect $E01E0C
- StdRRect $E01E10
- StdOval $E01E14
- StdArc $E01E18
- StdPoly $E01E1C
- StdRgn $E01E20
- StdPixels $E01E24
- StdComment $E01E28
- StdTxMeas $E01E2C
- StdTxBnds $E01E30
- StdGetPic $E01E34
- StdPutPic $E01E38
-
- When you call any of the standard procedures, the first direct page of QuickDraw
- II is active. If you pass variables on any direct page other than the first
- (direct page locations greater than $FF), you can use a simpletrick to access
- them. For example, to access TheFillPat ($10E) without changingthe direct page
- register:
-
- ldx #$100 ;offset to second DP
- lda >$OE,X ;gets "DP" location $10E
-
- Certain locations on the direct page are always valid:
-
- PortRef $24
- MaxWidth $20
- MasterSCB $08
- UserID $0A
-
- DrawVerb is usually valid, but not always:
-
- DrawVerb $38
-
- Each of the bottleneck procedures uses the direct page differently.
-
- QuickDraw II has an interesting bug relating to the standard conic bottleneck
- procedures. If you replace any of the standard procedures with your own,
- QuickDraw II does not perform some of the setups it normally would before
- calling the standard conic procedures (stdRRect, stdOval, stdArc). For example,
- if you replace StdRect with a custom rectangle routine, but leavethe other conic
- pointers alone (as shown in the code fragment above), QuickDrawII will not do
- all of the normal setups when calling the standard conicroutines. To deal with
- this bug of QuickDraw II, you must patch out the additional bottleneck
- procedures and set up those direct pages locations yourself, orthe results will
- not be what you expect. The QuickDraw II direct-page variables you must
- initialize yourself in this instance are bulleted (o) below.
-
- StdText
- DrawVerb $38 Describes the kind of text to draw. There
- are three possible values:
- DrawCharVerb 0
- DrawTextVerb 1
- DrawCStrVerb 2
- TextPtr $DA If the draw verb is DrawTextVerb or
- DrawCStrVerb, TextPtr points to the text
- buffer or C string to draw.
- TextLength $D8 If the draw verb is DrawTextVerb,
- TextLength contains the number of bytes in
- the text buffer.
- CharToDraw $D6 If the draw verb is DrawCharVerb,
- CharToDraw contains the character to draw.
-
- StdLine
- Y1 $A6 Starting Y value for the line to draw
- X1 $A8 Starting X value for the line to draw
- Y2 $AA Ending Y value for the line to draw
- X2 $AB Ending X value for the line to draw
- Rect2 $AE Exactly the same thing as Y1, X1, Y2 and
- X2 in the top, left, bottom, and right of
- the rectangle
-
- StdRect
- DrawVerb $38 One of the following five drawing verbs:
- Frame 0
- Paint 1
- Erase 2
- Invert 3
- Fill 4
- Rect1 $A6 The rectangle to draw in standard form
- (top, left, bottom, right)
- TheFillPat $10E The pattern to use for the rectangle if
- the verb is Fill
-
- Note: The QuickDraw II Auxiliary SpecialRect call does not use the
- rectangle bottleneck procedures.
-
- StdRRect
- DrawVerb $38 One of the following five drawing verbs:
- Frame 0
- Paint 1
- Erase 2
- Invert 3
- Fill 4
- Rect1 $A6 The boundary rectangle for the round
- rectangle
- OvalRect $295 A copy of the boundary rectangle for the
- round rectangle
- OvalHeight $208 The oval height for the rounded part of
- the round rectangle
- OvalWidth $20A The oval width for the rounded part of the
- round rectangle
- o ArcAngle $D2 Must be 360
- o StartAngle $D4 Must be zero
- TheFillPat $10E The pattern to use for the round rectangle
- if the verb is Fill
-
- StdOval
- DrawVerb $38 One of the following five drawing verbs:
- Frame 0
- Paint 1
- Erase 2
- Invert 3
- Fill 4
- Rect1 $A6 The boundary rectangle for the oval
- OvalRect $295 A copy of the boundary rectangle for the
- oval
- o OvalHeight $208 Must be the height of the oval
- o OvalWidth $20A Must be the width of the oval
- o ArcAngle $D2 Must be 360
- o StartAngle $D4 Must be zero
- TheFillPat $10E The pattern to use for the oval if the
- verb is Fill
-
- StdArc
- DrawVerb $38 One of the following five drawing verbs:
- Frame 0
- Paint 1
- Erase 2
- Invert 3
- Fill 4
- Rect1 $A6 The boundary rectangle for the arc
- o OvalWidth $20A Must be the width of the boundary
- rectangle for the arc
- ArcAngle $D2 The number of degrees the arc will sweep
- StartAngle $D4 The starting position of the arc
- TheFillPat $10E The pattern to use for the arc if the verb
- is Fill
-
- StdPoly
- DrawVerb $38 One of the following five drawing verbs:
- Frame 0
- Paint 1
- Erase 2
- Invert 3
- Fill 4
- RgnHandleA $50 The handle to the polygon data structure
- TheFillPat $10E The pattern to use for the polygon if the
- verb is Fill
-
- StdRgn
- DrawVerb $38 One of the following five drawing verbs:
- Frame 0
- Paint 1
- Erase 2
- Invert 3
- Fill 4
- RgnHandleC $70 The handle to the region to draw
- TheFillPat $10E The pattern to use for the region if the
- verb is Fill
-
- StdPixels
- SrcLocInfo $CC The LocInfo record for the source pixel
- map
- DestLocInfo $0C The LocInfo record for the destination
- pixel map
- SrcRect $DC The source rectangle for the operation in
- local coordinates for the source pixel map
- (as described in the source LocInfo
- record)
- DestRect $1C The destination rectangle for the
- operation in local coordinates for the
- destination pixel map (as described in the
- destination LocInfo record)
- XferMode $E4 The mode to use for data transfer
- RgnHandleA $50 The handle to the first region to which
- drawing is clipped (usually the ClipRgn
- from the GrafPort) A NIL handle is not
- allowed. To signify no clipping, pass a
- handle to the WideOpen region, which is
- defined as 10 bytes:
-
- Length $A (word)
- -MaxInt -$3FFF (word)
- -MaxInt -$3FFF (word)
- +MaxInt +$3FFF (word)
- +MaxInt +$3FFF (word)
-
- RgnHandleB $60 The handle to the second region to which
- drawing is clipped (usually the VisRgn
- from the GrafPort) A NIL handle is not
- allowed. To signify no clipping, pass a
- handle to the WideOpen region.
- RgnHandleC $70 The handle to the second region to which
- drawing is clipped (usually the mask
- region from the CopyPixels or the
- PaintPixels call) A NIL handle is not
- allowed. To signify no clipping, pass a
- handle to the WideOpen region.
-
- StdComment
- TheKind $A6 The kind of input for the comment
- TheSize $A8 The number of bytes to put into the
- picture
- TheHandle $AA The data to put into the picture
-
- StdTxMeas
- DrawVerb $38 Describes the kind of text to draw. There
- are three possible values:
- DrawCharVerb 0
- DrawTextVerb 1
- DrawCStrVerb 2
- TextPtr $DA If the draw verb is DrawTextVerb or
- DrawCStrVerb, TextPtr points to the text
- buffer or C string to draw.
- TextLength $D8 If the draw verb is DrawTextVerb,
- TextLength contains the number of bytes in
- the text buffer.
- CharToDraw $D6 If the draw verb is DrawCharVerb,
- CharToDraw contains the character to
- measure.
- TheWidth $DE The resulting width should be put here.
-
- StdTxBnds
- DrawVerb $38 Describes the kind of text to draw. There
- are three possible values:
- DrawCharVerb 0
- DrawTextVerb 1
- DrawCStrVerb 2
- TextPtr $DA If the draw verb is DrawTextVerb or
- DrawCStrVerb, TextPtr points to the text
- buffer or C string to draw.
- TextLength $D8 If the draw verb is DrawTextVerb,
- TextLength contains the number of bytes in
- the text buffer.
- CharToDraw $D6 If the draw verb is DrawCharVerb,
- CharToDraw contains the character to draw.
- RectPtr $D2 Indicates the address to put the resulting
- rectangle.
-
- StdGetPic
- This call takes input on the stack rather than the direct page. This is
- the one standard bottleneck procedure which you call with the direct
- page register set to something other than the direct page of QuickDraw
- II; it is set to a part of the stack.
-
- Stack Diagram on Entrance to StdGetPic
- Previous Contents
- DataPtr Pointer to destination buffer
- Count Integer (unsigned) (bytes to read)
- RTL Address 3 bytes
- ----------------- Top of Stack
-
- Stack Diagram just before exit from StdGetPic
- Previous Contents
- RTL Address 3 bytes
- ----------------- Top of Stack
-
- StdPutPic
- This call takes input on the stack rather than the direct page; however,
- unlike StdGetPic, the direct page for QuickDraw II is active when you
- call this routine.
-
- Stack Diagram on Entrance to StdPutPic
-
- Previous Contents
- DataPtr Pointer to source buffer
- Count Integer (unsigned) (bytes to read)
- RTL Address 3 bytes
- ----------------- Top of Stack
-
- Stack Diagram just before exit from StdPutPic
-
- Previous Contents
- RTL Address 3 bytes
- ----------------- Top of Stack
-
-
- Dealing with the Cursor
-
- The cursor can get in your way when you want to draw directly to the screen.
- QuickDraw II has two low-level routines which help you avoid this problem:
- ShieldCursor and UnshieldCursor. ShieldCursor tells QuickDraw II to hide the
- cursor if it intersects the MinRect and to prevent the cursor from moving until
- you call UnshieldCursor.
-
- There is a bug in ShieldCursor for System Disks 4.0 and earlier. This bug is
- related to the routine ObscureCursor. When the cursor is obscured, ShieldCursor
- does not prevent the cursor from moving; therefore, the user is able to move the
- cursor during a QuickDraw II operation, and this movementmay disturb the screen
- image.
-
- Calls to ShieldCursor must be balanced by calls to UnshieldCursor. You may not
- call ShieldCursor successively without calling UnshieldCursor after each call to
- ShieldCursor. There is no error checking, so careless use of these routines
- will result in an unusable system.
-
- MinRect is the smallest possible rectangle which encloses all the pixels that
- may be affected by a drawing call. You keep MinRect on the direct page and
- usually calculate it by intersecting the rectangle of the object you are drawing
- with the BoundsRect, PortRect, boundary box of the VisRgn, and the boundary box
- of the ClipRgn. You must set up MinRect yourself.
-
- ShieldCursor also looks at two other fields on the direct page of QuickDraw II.
- ImageRef is a long word located at $0E. If ImageRef does not point to $E12000
- or $012000, QuickDraw II assumes you are not drawing to the screen, so it does
- not have to shield the cursor. BoundsRect is a rectangle located at $14, and
- QuickDraw II uses it to translate MinRect into global coordinates. These values
- are generally correct, but under the following known circumstance,they are not
- and ShieldCursor will not function properly:
-
- 1. You have just drawn to an off-screen GrafPort with QuickDraw II.
- 2. You switch to a GrafPort on the screen.
- 3. You call ShieldCursor.
-
- ImageRef and BoundsRect are not updated until QuickDraw II is actually committed
- to drawing, thus, these values are still for the off-screenGrafPort in this
- case, even though you switched to a GrafPort on the screen. Therefore, when you
- call ShieldCursor, you have to make sure that thesevalues are current. (If
- these values are current, ShieldCursor will work correctly, no matter what the
- circumstances.)
-
- You can find the location of the QuickDraw II direct page with the GetWAP call.
- For speed reasons, you may not want to make the GetWAP call for each
- ShieldCursor call. You may wish to get the work area pointer value after
- starting QuickDraw II and store it for future reference.
-
- Calling ShieldCursor:
- 1. Set direct page for QuickDraw II.
- 2. Save the existing values of MinRect, ImageRef, and BoundsRect.
- 3. Set MinRect, ImageRef, and BoundsRect.
- 4. Let QuickDraw II know you've changed the contents of its direct page by
- clearing the "dirty" flags bits 14 to 0:
-
- DirtyFlags equ $EC
-
- ldx #$200 ;index to QD's third page of work
- lda DirtyFlags,x ;space
- and #$8000
- sta DirtyFlags,x
-
- 5. JSL to ShieldCursor.
- 6. Restore the previous values of MinRect, ImageRef, and BoundsRect.
-
- Note: Saving and restoring these values was not previously mentioned in this
- Note and in most circumstances it is not necessary. Saving and restoring
- is now recommended. In particular, if ShieldCursor is called inside a
- QuickDraw II bottleneck procedure, the system can crash if you fail to
- restore the contents of direct page.
-
- Calling UnshieldCursor:
- 1. Set direct page for QuickDraw II.
- 2. JSL to UnshieldCursor.
-
-
- ShieldCursor $E01E98
- MinRect $00
- ImageRef $0E
- BoundsRect $14
-
- UnshieldCursor $E01E9C
-
-
- Further Reference
- _____________________________________________________________________________
- o Apple IIGS Toolbox Reference, Volume 2
-